package com.vgulu.server.common.mongodb;

import com.mongodb.BasicDBObject;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.result.DeleteResult;
import com.vgulu.server.common.TConstant;
import org.bson.Document;
import org.bson.conversions.Bson;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by wangchunsee on 2016/11/8.
 */
public class MongoDbUtils {
    public static Document insertOne(String db,String col,Object data){
        MongoCollection<Document> collection = MongoDbFactory.getCollection(db,col);
        Document doc = transFrom(data);
        collection.insertOne(doc);
        return doc;
    }

    public static List<Document> insertMany(String db,String col,List data){
        MongoCollection<Document> collection = MongoDbFactory.getCollection(db,col);
        List<Document> ret = new ArrayList<>(data.size());
        for (Object o : data){
            Document doc = transFrom(o);
            collection.insertOne(doc);
            ret.add(doc);
        }
        return ret;
    }

    public static void updateMany(String db,String col, Bson filter, Object data){
        MongoCollection<Document> collection = MongoDbFactory.getCollection(db,col);
        Document doc = transFrom(data);
//        col.updateOne(Filters.eq("nick", "aaa"), new Document("$set", new Document("age", 33)));

        collection.updateMany(filter,new Document("$set",doc));
    }

    public static DeleteResult deleteOne(String db,String col, Bson filter){
        MongoCollection<Document> collection = MongoDbFactory.getCollection(db,col);
        return collection.deleteOne(filter);
    }

    public static DeleteResult deleteMany(String db, String col, Bson filter){
        MongoCollection<Document> collection = MongoDbFactory.getCollection(db,col);
        return collection.deleteMany(filter);
    }

    public static void updateOne(String db,String col, Bson filter, Object data){
        MongoCollection<Document> collection = MongoDbFactory.getCollection(db,col);
        Document doc = transFrom(data);
//        col.updateOne(Filters.eq("nick", "aaa"), new Document("$set", new Document("age", 33)));

        collection.updateOne(filter,new Document("$set",doc));
    }

    public static <T> List<T> find(String db,String col,Bson filter,MongoDataFactory<T> factory){
        return find(db,col,filter,factory,null,0,0);
    }

    public static <T> T findOne(String db,String col,Bson filter,MongoDataFactory<T> factory){
        List<T> result = find(db,col,filter,factory);
        if (result==null||result.isEmpty()){
            return null;
        }
        return result.get(0);
    }


    private static Document transFrom(Object o){
        String json = TConstant.gson.toJson(o);
        return  Document.parse(json);
    }

    public static <T> List<T>  find(String db, String col,Bson filter ,MongoDataFactory<T> factory , Bson sort, int skip, int pageSize) {
        return find(db,col,filter,factory,sort,skip,pageSize,null);
    }

    public static <T> List<T>  find(String db, String col,Bson filter,MongoDataFactory<T> factory , Bson sort, int skip, int pageSize, Bson field ) {
        MongoCollection<Document> collection = MongoDbFactory.getCollection(db,col);
        FindIterable<Document> d = filter==null?collection.find():collection.find(filter);
        if (sort!=null){
            d.sort(sort);
        }
        if (skip>0){
            d.skip(skip);
        }
        if (pageSize>0){
            d.limit(pageSize);
        }
        if (field!=null){
            d.projection(field);
        }
        MongoCursor<Document> cursor = d.iterator();
        List arr = new ArrayList();
        while (cursor.hasNext()){
            Document document=cursor.next();
            T o=factory.createData(document);
            if (o!=null){
                arr.add(o);
            }
        }
        return arr;
    }

    public static long count(String db, String col,Bson filter) {
        MongoCollection<Document> collection = MongoDbFactory.getCollection(db,col);
        return filter==null?collection.count():collection.count(filter);
    }
}
